import socket
import sys

from PyQt5 import QtWidgets
from PyQt5.QtCore import pyqtSignal, QObject, QThreadPool, QRunnable, Qt
from PyQt5.QtGui import QStandardItemModel, QStandardItem, QMouseEvent, QIntValidator
from PyQt5.QtWidgets import QMainWindow, QTextEdit, QTreeView


class GuiForTcpUdp(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)


class WorkerSignals(QObject):
    message = pyqtSignal(str)




class TcpServer(QRunnable):
    def __init__(self, host="127.0.0.1", port=9999):
        super().__init__()
        self.host = host
        self.port = port
        # 初始化信号对象，用于在线程中发送消息给主线程
        self.signals = WorkerSignals()

    def run(self) -> None:
        try:
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
                s.bind((self.host, self.port))
                s.listen(1)
                self.signals.message.emit(
                    f"TCP server started at {self.host}:{self.port}"
                )

                while True:
                    conn, addr = s.accept()
                    with conn:
                        self.signals.message.emit(f"Connected by {addr}")

                        while True:
                            data = conn.recv(1024)

                            if not data:
                                break
                            conn.sendall(data)

        except OSError as e:
            self.signals.message.emit(f"Error: {e.strerror}")


class UdpServer(QRunnable):
    def __init__(self, host="127.0.0.1", port=8888):
        super().__init__()
        self.host = host
        self.port = port

        # 初始化信号对象，用于在线程中发送消息给主线程
        self.signals = WorkerSignals()

    def run(self):
        try:
            with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
                s.bind((self.host, self.port))
                self.signals.message.emit(
                    f"UDP server started at {self.host}:{self.port}"
                )

                while True:
                    data, addr = s.recvfrom(1024)
                    self.signals.message.emit(f"Received from {addr}: {data}")
                    s.sendto(data, addr)

        except OSError as e:
            self.signals.message.emit(f"Error: {e.strerror}")


class MainWindow1(QMainWindow):
    def __init__(self):
        super().__init__()

        # 创建一个多行文本框，用于显示消息
        self.text_edit = QTextEdit(self)
        self.setCentralWidget(self.text_edit)

        # 创建线程池
        self.threadpool = QThreadPool()

        # 启动 TCP 服务端
        tcp_server = TcpServer()
        tcp_server.signals.message.connect(self.display_message)
        self.threadpool.start(tcp_server)

        # 启动 UDP 服务端
        udp_server = UdpServer()
        udp_server.signals.message.connect(self.display_message)
        self.threadpool.start(udp_server)

    def display_message(self, message):
        # 在多行文本框中显示消息
        cursor = self.text_edit.textCursor()
        cursor.movePosition(cursor.End)
        cursor.insertText(message + "")
        self.text_edit.setTextCursor(cursor)


class HeadBox(QtWidgets.QWidget):
    """添加头部"""

    def __init__(self, parent=None):
        super().__init__(parent)

        self.add_client = QtWidgets.QPushButton()
        self.add_client.setText("创建客户端")

        self.add_server = QtWidgets.QPushButton()
        self.add_server.setText("创建服务端")

        self.server_start = QtWidgets.QPushButton()
        self.server_start.setText("启动服务端")

        self.server_stop = QtWidgets.QPushButton()
        self.server_stop.setText("停止")

        self.server_remove = QtWidgets.QPushButton()
        self.server_remove.setText("移除服务端")

        transverse = QtWidgets.QHBoxLayout()  # 横向排序
        transverse.addWidget(self.add_client)
        transverse.addWidget(self.add_server)
        transverse.addWidget(self.server_start)
        transverse.addWidget(self.server_stop)
        transverse.addWidget(self.server_remove)

        self.setLayout(transverse)


class ClientBox(QtWidgets.QWidget):
    """左侧创建客户端和服务端的界面"""

    def __init__(self, parent=None):
        super().__init__(parent)

        self.model  = QStandardItemModel()
        self.node_root = self.model.invisibleRootItem()


        # 创建模型
        self.model = QStandardItemModel()
        self.model2 = QStandardItemModel()
        # 创建根节点
        # self.node_root = self.model.invisibleRootItem()

        self.node_client = QStandardItem("客户端模式")
        self.node_server = QStandardItem("服务端模式")

        self.model.appendRow(self.node_client)
        self.model.appendRow(self.node_server)

        self.tree_view = QTreeView()
        self.tree_view2 = QTreeView()

        # self.model.removeRow(0)
        self.tree_view.setModel(self.model)
        self.tree_view2.setModel(self.model2)

        transverse = QtWidgets.QVBoxLayout()  # 添加到Layout中
        transverse.addWidget(self.tree_view)
        transverse.addWidget(self.tree_view2)

        self.setLayout(transverse)


class MessageBox(QtWidgets.QWidget):
    """右侧消息盒子"""

    def __init__(self, parent=None):
        super().__init__(parent)

        self.host = QtWidgets.QLineEdit()
        self.host.setPlaceholderText("目标IP")
        self.port = QtWidgets.QLineEdit()
        self.port.setPlaceholderText("目标端口")

        self.specify_local_port = QtWidgets.QCheckBox()
        self.specify_local_port.setText("指定本地端口")

        self.local_port = QtWidgets.QLineEdit()
        self.local_port.setValidator(QIntValidator())

        self.protocol_combo = QtWidgets.QComboBox(self)
        self.protocol_combo.addItem("TCP")
        self.protocol_combo.addItem("UDP")

        self.num_of_send = QtWidgets.QLineEdit()
        self.num_of_rev = QtWidgets.QLineEdit()

        self.clear_button = QtWidgets.QPushButton()

        connection_information = QtWidgets.QVBoxLayout()
        connection_information.addWidget(QtWidgets.QLabel("目标IP"))
        connection_information.addWidget(self.host)
        connection_information.addWidget(QtWidgets.QLabel("目标端口"))
        connection_information.addWidget(self.port)

        self.setLayout(connection_information)


class MainWindow(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.drag_pos = None

        self.setWindowTitle("TCP/UDP工具")

        self.box_head = HeadBox(self)
        self.box_client = ClientBox(self)
        self.box_message = MessageBox(self)

        main_layout1 = QtWidgets.QVBoxLayout()  # 纵向排列
        # main_layout1.addWidget(self.box_head)

        main_layout2 = QtWidgets.QHBoxLayout()  # 横向排列
        main_layout2.addWidget(self.box_client)
        main_layout2.addWidget(self.box_message)

        # TODO:: 这行代码为何没有生效

        main_layout1.addWidget(self.box_head)
        main_layout1.addLayout(main_layout2)
        self.setLayout(main_layout1)

        # self.setLayout(main_layout2)

    def mousePressEvent(self, event: QMouseEvent):
        """
        鼠标按下事件
        :param event:
        :return:
        """
        if event.button() == Qt.LeftButton:
            self.drag_pos = event.globalPos()
            event.accept()

    def mouseMoveEvent(self, event: QMouseEvent):
        """
        鼠标移动事件
        :param event:
        :return:
        """
        if event.buttons() == Qt.LeftButton:
            self.move(self.pos() + event.globalPos() - self.drag_pos)
            self.drag_pos = event.globalPos()
            event.accept()


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())
